package cn.shoukaiseki.sjf4j.node;


import java.math.BigDecimal;
import java.util.Iterator;

public interface TreeNode {


    /**
     * 如果此节点是数字类型，则返回节点用于存储数值的本机类型；否则返回null。
     *
     * @return  包含的编号类型（如有）；如果节点不包含数值，则为null。
     * @since 1.0
     */
    NumberType numberType();


    int size();

    /**
     * 是否普通的值节点
     * <p>
     *    注意: 对于任何节点,{@link #isValueNode},
     *    {@link #isContainerNode} 和 {@link #isMissingNode} 只有一个方法会返回 true
     * @return {@code True} 不是对象,不是数组,不是无效的节点
     *         <p>
     *         {@code False} {@link #isContainerNode} 或者 {@link #isMissingNode} 其中一个结果为 {@code True}
     * @since 1.0
     */
    boolean isValueNode();

    /**
     * 是否容器节点(对象或者数组)
     * <p/>
     *    注意: 对于任何节点,{@link #isValueNode},
     *    {@link #isContainerNode} 和 {@link #isMissingNode} 只有一个方法会返回 true
     * @return  {@code True} 对象节点或者数组节点,{@link #isArray()} 或者{@link #isObject()} 方法有一个为 True
     * @since 1.0
     */
    boolean isContainerNode();


    /**
     * 是否为无效的节点
     * <p>
     *    注意: 对于任何节点,{@link #isValueNode},
     *    {@link #isContainerNode} 和 {@link #isMissingNode} 只有一个方法会返回 true
     * @return
     */
    boolean isMissingNode();

    /**
     * 是否为数组
     * <br>
     * 注意:  如果返回True, {@link #isContainerNode} 方法也一定返回 true
     * @return {@code true} json字符串中由 {@code []}解析后的节点
     * @since 1.0
     */
    boolean isArray();

    /**
     * 是否为对象
     * <br>
     * 注意:  如果返回True, {@link #isContainerNode} 方法也一定返回 true
     * @return {@code true} json字符串中由 {@code {}}解析后的节点
     * @since 1.0
     */
    boolean isObject();

    /**
     * 用于访问对象节点的指定字段的值的方法。如果此节点不是对象（或者它没有指定字段名称的值），或者没有具有该名称的字段，则返回null。
     * <p>
     * 注意：显式null值的处理可能因实现而异；一些节点可能保留显式null，而另一些节点则不保留。
     * @param fieldName 要访问的（对象节点的）字段的名称
     * @return 返回对象节点的值,否则返回 {@code null}
     * @since 1.0
     */
    TreeNode get(String fieldName);

    /**
     * 用于访问数组节点的指定元素的值的方法。对于其他节点，返回null。
     *<p>
     * 对于数组节点，索引指定了数组中的确切位置，并允许对子元素进行有效迭代（保证底层存储是有效可索引的，即可以随机访问元素）。如果index小于0，或者等于或大于
     * <code>node.size()</code>,则返回null；任何索引都不会引发异常。
     *
     * @param index 要访问的Array节点元素的索引
     *
     * @return 表示指定元素的值的节点，如果此节点是数组并具有指定元素；否则为{@code null}.
     *
     * @since 2.2
     */
    TreeNode get(int index);

    /**
     * 方法访问此节点的所有字段的名称，如果此节点是Object节点。可访问的字段名称的数量为{@link #size()}.
     *
     * @return 一个迭代器，用于遍历该Object节点所具有的所有字段的名称（如果是Object节点）；否则为空{@link Iterator} (不会返回{@code null})） .
     *
     * @since 2.2
     */
    Iterator<String> fieldNames();


    /**
     * 是否为数字节点
     * @return {@code True} 该节点的值为 数字类型
     */
    boolean isNumber();

    /**
     * 该方法可用于检查包含的值是否是用Java short表示的数字。
     * <p>
     * 注意，即使此方法返回false，也有可能从其他数字类型进行转换
     * <p>
     *  若要检查这是否可能,使用{@link #canConvertToInt()}方法代替
     * @return  {@code True} 此节点包含的值存储为Java short类型,{@link #isNumber}必定为true
     */
    boolean isShort();

    /**
     * 方法，可用于检查此节点是否为数字节点 ({@link #isNumber}将返回true)
     * 及其值是否适合Java的32位有符号整数类型int。
     * <p>
     * 请注意，如果整数部分适合而不溢出，则浮点数是可转换的（根据标准Java强制规则）
     * <p>
     * 注意: 此方法不考虑从JSON字符串到Number的可能的值类型转换；所以即使这个方法返回false，如果节点是表示整数或布尔值的JSON字符串，那么{@link #asInt}仍然有可能成功。
     *
     * @return
     */
    boolean canConvertToInt();

    /**
     * 该方法将尝试将该节点的值转换为Java int。使用默认Java规则强制使用数字；布尔值转换为0(false)和1(true)，字符串使用默认的Java语言整数解析规则进行解析。
     * <p>
     * 如果表示无法转换为int(包括Object和Arrays等结构化类型)，则返回默认值<b>0</b> ;不抛出任何异常。
     */
    int asInt();

    /**
     * 与{@link #asInt} 方法相同
     * <p>
     * 唯一区别是如果值为null,则返回null
     */
    Integer asIntVal();

    /**
     * 该方法将尝试将此节点的值转换为Java long。使用默认Java规则强制数字；布尔值转换为0（false）和1（true），字符串使用默认的Java语言整数解析规则进行解析。
     * <p>
     * 如果表示无法转换为长（包括Object和Arrays等结构化类型），则返回默认值<b>0</b>；不抛出任何异常。
     */
    long asLong();

    /**
     * 与{@link #asLong} 方法相同
     * <p>
     * 唯一区别是如果值为null,则返回null
     */
    Long asLongVal();

    boolean asBoolean();

    /**
     * 与{@link #asBoolean} 方法相同
     * <p>
     * 唯一区别是如果值为null,则返回null
     */
    Boolean asBooleanVal();

    double asDouble();

    /**
     * 与{@link #asDoubleVal} 方法相同
     * <p>
     * 唯一区别是如果值为null,则返回null
     */
    Double asDoubleVal();


    /**
     * 如果值为null,则返回null
     */
    BigDecimal asDecimalVal();

    /**
     * 是否为null
     * @return      {@code True} 值为null
     */
    boolean isNull();

    /**
     *
     * 用于访问字符串值的方法。不对非String值节点进行任何转换；对于非字符串值（{@link #isTextual}返回false的值），将返回null。
     * <p>
     * 对于字符串值，从不返回null（但可以返回空字符串）
     *
     */
    String textValue();

    /**
     * 该方法检查此节点是否表示基本的JSON字符串值
     */
     boolean isTextual();


    boolean isBigDecimal();

    /**
     * 节点类型
     */
    JsonNodeType getNodeType();
}
